﻿using Microsoft.Phone.Shell;
using MobiSms.DataModel;
using MobiSms.Enums;
using MobiSms.Library.Extensions;
using MobiSms.Library.Helpers;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using MobiSms.Library;

namespace MobiSms.ViewModel
{
    public class ReplyViewModel : MainViewModel
    {
        #region Constructor
        public ReplyViewModel()
        {
            SoapClient.MOCompleted -= RequestReplyCompleted;
            SoapClient.MOCompleted += RequestReplyCompleted;
            if (!IsDesignMode)
            {
                LoadReplyOfMonth();
                RequestReply();
                //
            }
        } 
        #endregion

        #region Properties
        /*
        private MonthOfYear _selectedMonth = (MonthOfYear)DateTime.Now.Month;
        public MonthOfYear SelectedMonth
        {
            get { return _selectedMonth; }
            set
            {
                _selectedMonth = value;
                RaisePropertyChanged(() => SelectedMonth);
                RaisePropertyChanged(() => ItemsOfReply);
            }
        }
         */

        private DateTime _selectedMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
        public DateTime SelectedMonth
        {
            get { return _selectedMonth; }
            set
            {
                _selectedMonth = value;
                RaisePropertyChanged(() => SelectedMonth);
                if (!IsDesignMode)
                {
                    LoadReplyOfMonth();
                }
            }
        }

        public int ItemsCount
        {
            get
            {
                if (IsDesignMode)
                {
                    return 0;
                }
                return Database.CollectionOfReplies.Count();
            }
        }

        private int _newCount = 0;
        public int NewCount
        {
            get { return _newCount; }
            set
            {
                _newCount = value;
                RaisePropertyChanged(() => NewCount);
            }
        }

        private int _unreadCount = 0;
        public int UnreadCount
        {
            get { return _unreadCount; }
            set
            {
                _unreadCount = value;
                RaisePropertyChanged(() => UnreadCount);
                SetShellTile();
            }
        }

        private int _index = 0;
        private SerialInfo _requestSerial;

        private ObservableCollection<ReplyInfo> _itemsOfReply = new ObservableCollection<ReplyInfo>();
        public ObservableCollection<ReplyInfo> ItemsOfReply
        {
            get { return _itemsOfReply; }
            set
            {
                _itemsOfReply = value;
                RaisePropertyChanged(() => ItemsOfReply);
                RaisePropertyChanged(() => LoadPreviousCommand);
            }
        }

        public IEnumerable<MonthOfYear> Months
        {
            get
            {
                return EnumHelper.GetEnumValues<MonthOfYear>();
            }
        }
        #endregion

        #region Events & Methods
        private void LoadReplyOfMonth()
        {
            IEnumerable<ReplyInfo> items = Database.CollectionOfReplies.Where(m => m.Time > SelectedMonth && m.Time < SelectedMonth.AddMonths(1));

            ItemsOfReply = new ObservableCollection<ReplyInfo>(ItemsOfReply.Concat(items).OrderByDescending(m => m.Time));

            if (items.Count() == 0 && ItemsOfReply.Count < ItemsCount)
            {
                SelectedMonth = SelectedMonth.AddMonths(-1);
            }
        }

        private void RequestReplyCompleted(object sender, MOCompletedEventArgs e)
        {
            if (e.Error == null && e.Result.code == 0)
            {
                NewCount += e.Result.list.Count();
                IEnumerable<ReplyInfo> items = e.Result.list.Select(c => new ReplyInfo()
                {
                    Content = c.content,
                    Extension = c.ext,
                    Mobile = c.mobile,
                    Time = DateTime.Parse(c.time),
                    Serial = _requestSerial.SerialNumber
                });
                Database.CollectionOfReplies.InsertAllOnSubmit(items);
                Submit();
                foreach (var item in items.OrderBy(r => r.Time))
                {
                    ItemsOfReply.Insert(0, item);
                }
            }
            _index++;
            RequestReply();
        }

        public void RequestReply()
        {
            if (ItemsOfSerial != null && ItemsOfSerial.Count > 0 && _index < ItemsOfSerial.Count)
            {
                _requestSerial = ItemsOfSerial[_index];
                SoapClient.MOAsync(_requestSerial.SerialNumber, _requestSerial.Password);
            }
            else
            {
                _index = 0;
                if (NewCount > 0)
                {
                    ShellToast toast = new ShellToast();
                    toast.Title = Application.Current.FindResource<string>(LanguageKeys.IDS_APP_TOAST_TITLE);
                    toast.Content = string.Format(Application.Current.FindResource<string>(LanguageKeys.IDS_NOTIFICATION_RECIEVE_NEWMSG), NewCount);
                    toast.NavigationUri = new Uri("/Views/ReplyCollection.xaml?param=abc&param2=xyz", UriKind.Relative);
                    toast.Show();
                }

            }
            //Deployment.Current.Dispatcher.BeginInvoke(() =>
            //{
            //    UnreadCount = Database.CollectionOfReplies.Count(r => r.Status == ReplyMessageStatusValue.Unread);
            //    RaisePropertyChanged(() => UnreadCount);
            //});
            GetUnreadMessages();
        }

        public void GetUnreadMessages()
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                UnreadCount = Database.CollectionOfReplies.Count(r => r.Status == ReplyMessageStatusValue.Unread);
                RaisePropertyChanged(() => UnreadCount);
            });
        }

        private void SetShellTile()
        {
            ShellTile applicationTile = ShellTile.ActiveTiles.First();
            StandardTileData newTile = new StandardTileData
            {
                Count = UnreadCount
            };
            applicationTile.Update(newTile);
        }
        #endregion

        public ICommand LoadPreviousCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return ItemsOfReply == null || ItemsOfReply.Count < ItemsCount; },
                    ExecuteCallback = delegate
                    {
                        SelectedMonth = SelectedMonth.AddMonths(-1);
                    }
                };
            }
        }
    }
}
